package singleton
{
	import Main.TransformationHandler;
	import Main.UploadHandler;
	import Main.WSMDA_New;
	import Main.XMLViewer;
	
	import flash.events.TimerEvent;
	import flash.system.Security;
	import flash.utils.ByteArray;
	import flash.utils.Timer;
	
	import mx.controls.Alert;
	import mx.controls.DataGrid;
	import mx.controls.Image;
	import mx.controls.Menu;
	import mx.controls.MenuBar;
	import mx.controls.ProgressBar;
	import mx.effects.Sequence;
	import mx.managers.PopUpManager;
	import mx.rpc.soap.WebService;
	
	import spark.components.BorderContainer;
	import spark.components.Button;
	import spark.components.Label;
	import spark.components.TextInput;

	public class GUIController
	{
		public static var MENU_UPLOAD:String = "menu upload", MENU_EXECUTION:String = "menu execution", MENU_HELP:String = "menu help", UPLOAD:String = "upload", EXECUTE:String = "execute", SRC_MODEL:String = "source model",
			SRC_METAMODEL:String = "source metamodel" ,TRGT_METAMODEL:String = "target metamodel", ATL_FILE:String = "atl", UPLOAD_SOURCE:String = "upload source", UPLOAD_TARGET:String = "upload target",
			RULES:String = "rules", DOWNLOAD:String = "download", INFO:String = "info", VIEW:String = "view", SHAKE:String = "shake", WARN:String = "warn", OK:String = "ok", POINT:String = "point",
			TO_UPLOAD:String = "to upload", TO_EXECUTE:String = "to execute", SRC_MM_INPUT_NAME:String = "srcMMInputName", TRGT_MM_INPUT_NAME:String = "trgtMMInputName", SRC_MODEL_INPUT_NAME:String = "source input name";
		private static var controller:GUIController;
		private static var wsmda:WSMDA_New;
		private static var session:Session = Session.getInstance();
		private static var timer:Timer = new Timer(1000);
		private static var seconds:int = 0, minutes:int = 5;
		public function GUIController(mda:WSMDA_New, sk:SingletonKeeper)
		{
			if (sk == null) {
				throw new Error();
			}
			wsmda = mda;
		}
		
		/**
		 * Singleton initializer.
		 * */
		public static function init(mda:WSMDA_New):void {
			
			controller = new GUIController(mda, new SingletonKeeper());
			
			controller.getWebService().getNewSessionId();
			timer.addEventListener(TimerEvent.TIMER, timerUpdate);
			timer.start();
			
		}
		
		public static function getInstance():GUIController {
			if (controller == null) {
				throw new Error("You must initialize it first!");
			}
			return controller;
		}
		
		protected static function timerUpdate(evt:TimerEvent):void {
			
			seconds--;
			if (seconds <= 0 && minutes > 0) {
				seconds = 59;
				minutes--;
			}
			wsmda.timer.text = "Session expires in: " + minutes + ":" + seconds;
			if (seconds == 0 && minutes == 0) {
				timer.stop();
				wsmda.timer.text = "Session expired";
				
			}
			
			
		}
		
		/**
		 * Restarts the session timer
		 * */
		public function restartTimer():void {
			seconds = 0;
			minutes = 5;
			timer.start();
		}
		
		/**
		 * Returns the corresponding Button, according to the 'type' parameter.
		 * @param type - String with one of the following names: <i>menu upload</i>, <i>menu execution</i>, <i>menu help</i>, <i>upload</i>,
		 *  <i>execute</i>, <i>atl</i>, <i>source metamodel</i>, <i>target metamodel</i>, <i>source model</i>, <i>rules</i>, <i>download</i>,
		 *  <i>to upload</i>, <i>to execute</i> or <i>view</i>
		 * @return The corresponding Button. Null if 'type' is invalid.
		 * */
		public function getButton(type:String):Button {
			if (type == MENU_UPLOAD) {
				return wsmda.toMainButton;
			}
			if (type == MENU_EXECUTION) {
				return wsmda.goToMenu2;
			}
			if (type == MENU_HELP) {
				return wsmda.backToMenu;
			}
			if (type == UPLOAD) {
				return wsmda.uploadUpButton;
			}
			if (type == EXECUTE){
				return wsmda.executeButton;
			}
			if (type == ATL_FILE) {
				return wsmda.selectATLFileButton;
			}
			if (type == SRC_METAMODEL) {
				return wsmda.sourceMMButton2;
			}
			if (type == TRGT_METAMODEL) {
				return wsmda.targetMMButton;
			}
			if (type == SRC_MODEL) {
				return wsmda.sourceModelFileButton;
			}
			if (type == RULES) {
				return wsmda.selectAllRules;
			}
			if (type == DOWNLOAD) {
				return wsmda.downloadButton;
			}
			if (type == VIEW) {
				return wsmda.viewXMLButton;
			}
			if (type == TO_EXECUTE) {
				return wsmda.toExecuteStateButton;
			}
			if (type == TO_UPLOAD) {
				return wsmda.toUploadStateButton;
			}
			return null;
		}
		
		/**
		 * Returns the corresponding TextInput, according to the 'type' parameter.
		 * @param type - String with one of the following names: <i>atl</i>, <i>source metamodel</i>, <i>target metamodel</i>, <i>rules</i> or <i>source model</i>
		 * @return The corresponding TextInput. Null if 'type' is invalid.
		 * */
		public function getTextInput(type:String):TextInput {
			if (type == ATL_FILE) {
				return wsmda.atlInput;
			}
			else if (type == SRC_METAMODEL) {
				return wsmda.sourceMMInput;
			}
			else if (type == TRGT_METAMODEL) {
				return wsmda.targetMMInput;
			}
			else if (type == SRC_MODEL) {
				return wsmda.sourceModelInput;
			}
			else if (type == RULES) {
				return wsmda.ruleDependencies;
			}
			else if (type == SRC_MODEL_INPUT_NAME) {
				return wsmda.sourceModelInputName;
			}
			return null;
		}
		
		/**
		 * Returns the corresponding Label, according to the 'type' parameter.
		 * @param type - String with one of the following names: <i>atl</i>, <i>source metamodel</i>, <i>target metamodel</i>, <i>source model</i>,
		 *  <i>info</i>, <i>upload source</i>, <i>upload target</i>, <i>download</i> or <i>view</i>
		 * @return The corresponding Label. Null if 'type' is invalid.
		 * */
		public function getLabel(type:String):Label {
			
			if (type == ATL_FILE) {
				return wsmda.transformationName;
			}
			if (type == SRC_METAMODEL) {
				return wsmda.sourceMMName;
			}
			if (type == TRGT_METAMODEL) {
				return wsmda.targetMMName;
			}
			if (type == SRC_MODEL) {
				return wsmda.modelName;
			}
			if (type == DOWNLOAD) {
				return wsmda.fileSizeLabel;
			}
			if (type == INFO) {
				return wsmda.infoDownload;
			}
			return null
		}
		
		/**
		 * Returns the corresponding DataGrid, according to the 'type' parameter.
		 * @param type - String with one of the following names: <i>atl</i> or <i>rules</i>
		 * @return The corresponding DataGrid. Null if 'type' is invalid.
		 * */
		public function getDataGrid(type:String):DataGrid {
			if (type == ATL_FILE) {
				return wsmda.availTransformations;
			}
			if (type == RULES) {
				return wsmda.atlRules;
			}
			return null;
		}
		
		/**
		 * Returns the component's current state.
		 * */
		public function getCurrentState():String {
			return wsmda.currentState;
		}
		
		/**
		 * Returns the corresponding ProgressBar, according to the 'type' parameter.
		 * @param type - String with one of the following names: <i>upload</i> or <i>execute</i>
		 * @return The corresponding TextInput. Null if 'type' is invalid.
		 * */
		public function getProgressBar(type:String):ProgressBar {
			if (type == UPLOAD) {
				return wsmda.lilProgress;
			}
			if (type == EXECUTE) {
				return wsmda.progress;
			}
			return null;
		}
		
		/**
		 * Returns the corresponding Sequence action, according to the 'type' parameter.
		 * @param type - String with one of the following names: <i>shake</i>, <i>upload</i>, <i>download</i> or <i>execute</i>
		 * @return The corresponding TextInput. Null if 'type' is invalid.
		 * */
		public function getAction(type:String):Sequence {
			if (type == SHAKE) {
				return wsmda.treme;
			}
			if (type == UPLOAD) {
				return wsmda.acao;
			}
			if (type == EXECUTE) {
				return wsmda.showTrOpt;
			}
			if (type == DOWNLOAD) {
				return wsmda.expandBorderTransformation;
			}
			return null;
		}
		
		/**
		 * Returns the corresponding Image, according to the 'type' parameter.
		 * @param type - String with one of the following names: <i>warn</i>, <i>point</i>, <i>atl</i> or <i>ok</i>
		 * @return The corresponding TextInput. Null if 'type' is invalid.
		 * */
		public function getImage(type:String):Image {
			if (type == WARN) {
				return wsmda.warnImage;
			}
			if (type == OK) {
				return wsmda.doneImage;
			}
			if (type == POINT) {
				return wsmda.pointImage;
			}
			if (type == ATL_FILE) {
				return wsmda.showAtlCodeImg;
			}
			if (type == SRC_METAMODEL) {
				return wsmda.srcMMCode;
			}
			if (type == TRGT_METAMODEL) {
				return wsmda.trgtMMCode;
			}
			return null;
		}
		
		/**
		 * Changes the actual state, according to the 'type' parameter.
		 * @param type - String with one of the following names: <i>upload</i>, <i>execute</i> or <i>info</i>. If it doesn't match one of those, the
		 * state will change to the default one (Main).
		 * */
		public function changeState(type:String):void {
			if (type == UPLOAD) {
				wsmda.currentState = "Uploading";
			} else if (type == EXECUTE) {
				wsmda.currentState = "Transformation";
			} else if (type == INFO) {
				wsmda.currentState = "Help";
			} else {
				wsmda.currentState = "Main";
			}
			
		}
		
		/**
		 * Returns the corresponding BorderContainer, according to the 'type' parameter.
		 * @param type - String with one of the following names: <i>upload</i> or <i>execute</i>
		 * @return The corresponding BorderContainer. Null if 'type' is invalid.
		 * */
		public function getBorderContainer(type:String):BorderContainer {
			if (type == UPLOAD) {
				return wsmda.BorderUploading;
			}
			if (type == EXECUTE) {
				return wsmda.borderTransformation;
			}
			return null;
		}
		
		/**
		 * Returns the main menu bar
		 * */
		public function getMenu():MenuBar {
			return wsmda.menu;
		}
		
		/**
		 * Handles the menu clicks
		 * */
		public function menuClicked():void {
			var index:int = getMenu().selectedIndex;
			
			var m:Menu = getMenu().getMenuAt(index);
			
			switch (index) {
				case 0:
					if (m.selectedIndex == 0) {
						UploadHandler.initState();
					} else if (m.selectedIndex == 1) {
						TransformationHandler.initState();
					}
					break;
				case 1:
					if (m.selectedIndex == 0) {
						changeState(INFO);
					} else if (m.selectedIndex == 1) {
						//todo
					}
					break;
				default:
					//nada
			}
			
			
		}
		
		/**
		 * Shows the XML Viewer window with the corresponding XML File.
		 * @param downloadable - ByteArray with the XML File content.
		 * */
		public function showPopUp(downloadable:ByteArray):void {
			var prefsXML:XML = XML(downloadable);
			var viewer:XMLViewer = new XMLViewer();
			viewer.textInfo.text = "\n" + prefsXML.toXMLString();
			PopUpManager.addPopUp(viewer, wsmda, true);
			PopUpManager.centerPopUp(viewer);
		}
		
		/**
		 * Shows the XML Viewer window with the corresponding XML File.
		 * @param downloadable - ByteArray with the XML File content.
		 * */
		public function showPopUpString(string:String):void {
			var viewer:XMLViewer = new XMLViewer();
			viewer.textInfo.text = "\n" + string;
			PopUpManager.addPopUp(viewer, wsmda, true);
			PopUpManager.centerPopUp(viewer);
		}
		
		/**
		 * Returns the current WebService.
		 * */
		public function getWebService():WebService {
			return wsmda.M2MTransformationService;
		}
		
	}
	
	
}